import { Injectable } from '@angular/core';
import { JwtHelper } from 'angular2-jwt';
import { Http, Response, RequestOptions, Headers } from '@angular/http';
import { ConfigService } from '../../core/common/config.service';
import { Router, ActivatedRoute } from '@angular/router';

@Injectable()
export class User {
  jwtHelper: JwtHelper = new JwtHelper();
  constructor(private route: ActivatedRoute, private http: Http, private config: ConfigService, private router: Router) {
    const token = window.sessionStorage.getItem('token');
    if (token) {
      const jwt = this.jwtHelper.decodeToken(token);
      this.initUser(jwt);
      this.addRefresh(jwt.exp);
    }
  }
  public get account(): string {
    let result = null;
    const token = window.sessionStorage.getItem('token');
    if (token && token !== '') {
      const jwt = this.jwtHelper.decodeToken(token);
      result = jwt.account;
    }
    return result;
  }
  public get userID(): string {
    let result = null;
    const token = window.sessionStorage.getItem('token');
    if (token && token !== '') {
      const jwt = this.jwtHelper.decodeToken(token);
      result = jwt.userID;
    }
    return result;
  }
  private initUser(jwt: any): void {

  }
  public get firstLogin(): boolean {
    const firstLogin = window.sessionStorage.getItem('firstLogin');
    if (firstLogin) {
      return firstLogin === 'true';
    } else {

      const token = window.sessionStorage.getItem('token');
      if (token && token !== '') {
        const jwt = this.jwtHelper.decodeToken(token);
        return jwt.firstLogin;
      } else {
        return false;
      }
    }
  }
  public init(data: any): boolean {
    if (data.token) {
      window.sessionStorage.setItem('token', data.token);
    }
    if (data.refresh_token) {
      window.sessionStorage.setItem('refresh_token', data.refresh_token);
    }
    const jwt = this.jwtHelper.decodeToken(data.token);
    this.initUser(jwt);
    this.addRefresh(jwt.exp);
    const url = this.config.get('url') + '?service=FuncService&method=getFuncList';
    this.http.post(url, null).toPromise().then((resp: Response) => {
      const result = resp.json();
      if (result.code === '0000') {
        window.sessionStorage.setItem('userFunction', JSON.stringify(result.info));
      }
    });
    return true;
  }
  private addRefresh(expire): void {
    const exp = parseInt(expire, 10) * 1000;
    const offset = exp - new Date().getTime();
    setTimeout(() => {
      this.refreshToken();
    }, offset);
  }

  public destroy() {
    window.sessionStorage.clear();
  }
  public checkUserFunction(code: string): boolean {
    let result = false;
    const userFunctionList = JSON.parse(window.sessionStorage.getItem('userFunction'));
    userFunctionList.forEach((f: any) => {
      if (f.code === code) {
        result = true;
      }
    });
    return result;
  }
  public hasRole(roleId: number): boolean {
    let result = false;
    const token = window.sessionStorage.getItem('token');
    if (token && token !== '') {
      const jwt = this.jwtHelper.decodeToken(token);
      const roleList = jwt.roleList;
      roleList.forEach((f: any) => {
        if (f.roleId === roleId) {
          result = true;
        }
      });
    }
    return result;
  }
  private refreshToken(): void {
    const tokenName = this.config.get('auth.refresh_token');
    const refreshUrl = this.config.get('url') + '?service=TokenService&method=refreshToken';
    const refresh_token = window.sessionStorage.getItem('refresh_token');
    this.http.post(refreshUrl, { refreshToken: refresh_token }, new RequestOptions({
      headers:
      new Headers({ tokenName, refresh_token })
    })).toPromise()
      .then((resp: Response) => {
        const result = resp.json();
        if (result.code === '0000') {
          this.init(result.info);
        }
      });
  }
  public isLoggedIn(): Promise<boolean> {
    const token = window.sessionStorage.getItem('token');
    if (token && token !== '') {
      const jwt = this.jwtHelper.decodeToken(token);
      const exp = parseInt(jwt.exp, 10) * 1000;
      if (exp > new Date().getTime()) {
        return Promise.resolve(true);
      }
    }
    return Promise.resolve(false);
  }
}
